<template>
  <div class="file-upload">
    <div class="file-upload-container" @click.prevent="triggerUpload" v-bind="attrs">
      <slot v-if="fileStatus === 'ready'" name="default">
        <button class="btn btn-primary m-auto d-block mt-3">点击上传</button>
      </slot>
      <slot v-else-if="fileStatus === 'loading'" name="loading">
        <button class="btn btn-primary">正在上传...</button>
      </slot>
      <slot v-else-if="fileStatus === 'success'" name="success" :uploadData="uploadData">
        <button class="btn btn-primary ">上传成功</button>
      </slot>
    </div>
    <input type="file" class="file-input d-none" ref="fileInput" @change="handleFileChange">
  </div>
</template>

<script setup lang="ts">
import { ref, useAttrs, watch } from 'vue';
import { ImageProps } from '../store/store';
import { reqPostFile } from '../api/request';
type UpladStatus = 'ready' | 'loading' | 'success' | 'error'
interface Props {
  // File 文件类型
  beforUpload: (file: File) => boolean
  uploaded: ImageProps
}
// 获取 props   withDefaults 设置默认值
const props = defineProps<Props>()
// 获取自定义事件
const emits = defineEmits(['file-success', 'file-error'])
// input 节点
const fileInput = ref<null | HTMLInputElement>(null)
// input状态
const fileStatus = ref<UpladStatus>(props.uploaded ? 'success' : 'ready')
const triggerUpload = () => {
  if (fileInput.value) {
    // 手动触发 
    fileInput.value.click()
  }
}
const uploadData = ref(props.uploaded)
// 点击事件回调
const handleFileChange = (e: Event) => {
  const currentTarget = e.target as HTMLInputElement
  if (currentTarget.files) {
    // 转换为数组
    const files = Array.from(currentTarget.files)
    // 判断有没有beforUpload
    if (props.beforUpload) {
      const result = props.beforUpload(files[0])
      if (!result) return
    }
    // 创建FormData 对象
    const fromData = new FormData()
    // 把文件添加到FormData对象里
    fromData.append('file', files[0])
    fileStatus.value = 'loading'
    reqPostFile(fromData).then((res) => {
      // 发送成功时
      fileStatus.value = 'success'
      // 触发自定义事件
      emits('file-success', res.data)
      uploadData.value = res.data.data
    }).catch((e) => {
      fileStatus.value = 'error'
      emits('file-error', { e })
    }).finally(() => {
      if (fileInput.value) {
        fileInput.value.value = ''
      }
    })
  }
}
const attrs = useAttrs()
watch(() => props.uploaded, (newValue) => {
  if (newValue) {
    fileStatus.value = 'success'
    uploadData.value = newValue
  }
})

</script>